package com.daffodil.monitor.controller;

import java.util.Iterator;
import java.util.Properties;
import java.util.TreeMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.daffodil.core.entity.JsonResult;
import com.daffodil.framework.annotation.AuthPermission;
import com.daffodil.monitor.constant.MonitorConstant;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
import springfox.documentation.annotations.ApiIgnore;

/**
 * -Redis缓存监控管理
 * @author yweijian
 * @date 2022年9月30日
 * @version 2.0.0
 * @description
 */
@Api(value = "缓存监控管理", tags = "缓存监控管理")
@Slf4j
@RestController
@RequestMapping(MonitorConstant.API_CONTENT_PATH)
public class SysRedisCacheController {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @ApiOperation("获取Redis缓存健康信息数据")
    @ApiImplicitParam(name = HttpHeaders.AUTHORIZATION, value = "登录授权令牌 Bearer token", paramType = "header", required = true)
    @AuthPermission("monitor:rediscache:health")
    @GetMapping("/rediscache/health")
    public Mono<JsonResult> health(@ApiIgnore ServerHttpRequest request){
        RedisConnectionFactory factory = redisTemplate.getRequiredConnectionFactory();
        try {
            TreeMap<Object, Object> treeMap = new TreeMap<Object, Object>((a, b) -> ((String) a).compareTo((String) b));
            String mode = factory.getConnection().info().getProperty("redis_mode");
            if("standalone".equals(mode)) {
                Properties properties = factory.getConnection().info("all");
                treeMap.putAll(properties);
                return Mono.just(JsonResult.success(treeMap));
            }else {
                Iterator<RedisClusterNode> iterator = factory.getClusterConnection().clusterGetNodes().iterator();
                while (iterator.hasNext()) {
                    RedisClusterNode node = iterator.next();
                    if(node.isMaster() && treeMap.isEmpty()) {
                        Properties properties = factory.getClusterConnection().info(node, "all");
                        treeMap.putAll(properties);
                    }
                }
                return Mono.just(JsonResult.success(treeMap));
            }
        }catch (IllegalStateException e) {
            log.error(e.getMessage(), e);
            return Mono.just(JsonResult.error());
        }
    }
}
